home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 112 / EnigmaAmiga112CD.iso / dalla rivista / news / orbit / source / player.c < prev    next >
C/C++ Source or Header  |  2000-05-01  |  11KB  |  434 lines

  1. /*
  2.     Amiga port by Oliver Gantert
  3.  
  4.     27.04.2000 - fixed some compiler warnings
  5. */
  6. /*
  7.  
  8. ORBIT, a freeware space combat simulator
  9. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  10.  
  11. This program is free software; you can redistribute it and/or
  12. modify it under the terms of the GNU General Public License
  13. as published by the Free Software Foundation; either version 2
  14. of the License, or (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  24.  
  25. */
  26.  
  27. #include "orbit.h"
  28.  
  29. void InitPlayer()
  30. /*
  31.  *  Set up initial player position, etc.
  32.  */
  33. {
  34.   /* Initial position */
  35.   player.pos[0] = planet[3].pos[0] - 2.0*planet[3].radius;
  36.   player.pos[1] = planet[3].pos[1];
  37.   player.pos[2] = planet[3].pos[2];
  38.  
  39.   /* Up vector */
  40.   player.up[0] = 0.0;
  41.   player.up[1]= 0.0;
  42.   player.up[2] = 1.0;
  43.  
  44.   /* Viewing vector */
  45.   player.view[0] = 1.0;
  46.   player.view[1] = 0.0;
  47.   player.view[2] = 0.0;
  48.  
  49.   /* Right-hand vector */
  50.   Crossp (player.right, player.up, player.view);
  51.   Normalize (player.right);
  52.  
  53.   /* Velocity components */
  54.   player.vel[0] = player.vel[1] = player.vel[2] = 0.0;
  55.   player.throttle = 0.0;
  56.  
  57.   /* Shields */
  58.   player.shields = player.maxshields = 100.0;
  59.  
  60.   /* Weapon */
  61.   player.weapon = 0;
  62.   player.msl_idle = 0.0;
  63. }
  64.  
  65. void MovePlayer()
  66. {
  67.   double v[3], theta, deltav[3];
  68.   int p, t, was_still;
  69.   char buf[128]; 
  70.   
  71.   /* Aim player if view is locked */ 
  72.   if (player.viewlock) ViewLock(); 
  73.   
  74.   /* Compute angle to move, given time change */
  75.   theta = THETA * deltaT;
  76.  
  77.   /* Deltav will be change in velocity components due to thrust */
  78.   deltav[0] = deltav[1] = deltav[2] = 0.0;
  79.  
  80.   /* Keep track if we've gone from still to not still or vice versa */ 
  81.   was_still = player.still; 
  82.   player.still = 1; 
  83.   
  84.   if (player.move_left > 0.0)
  85.   {
  86.     RotateAbout (v, player.view, player.up, -theta*player.move_left);
  87.     Vset (player.view, v);
  88.     Normalize (player.view);
  89.     Crossp (player.right, player.up, player.view);
  90.     Normalize (player.right); 
  91.     player.still = 0;
  92.   }
  93.  
  94.   if (player.move_right > 0.0)
  95.   {
  96.     RotateAbout (v, player.view, player.up, theta*player.move_right);
  97.     Vset (player.view, v);
  98.     Normalize (player.view);
  99.     Crossp (player.right, player.up, player.view);
  100.     Normalize (player.right); 
  101.     player.still = 0;
  102.   }
  103.  
  104.   if (player.move_up > 0.0)
  105.   {
  106.     RotateAbout (v, player.view, player.right, theta*player.move_up);
  107.     Vset (player.view, v);
  108.     Normalize (player.view);
  109.     Crossp (player.up, player.view, player.right);
  110.     Normalize (player.up); 
  111.     player.still = 0;
  112.   }
  113.  
  114.   if (player.move_down > 0.0)
  115.   {
  116.     RotateAbout (v, player.view, player.right, -theta*player.move_down);
  117.     Vset (player.view, v);
  118.     Normalize (player.view);
  119.     Crossp (player.up, player.view, player.right);
  120.     Normalize (player.up); 
  121.     player.still = 0;
  122.   }
  123.  
  124.   if (player.move_pitchright > 0.0)
  125.   {
  126.     RotateAbout (v, player.up, player.view, -theta*player.move_pitchright);
  127.     Vset (player.up, v);
  128.     Normalize (player.up);
  129.     Crossp (player.right, player.up, player.view);
  130.     Normalize (player.right); 
  131.     player.still = 0;
  132.   }
  133.  
  134.   if (player.move_pitchleft > 0.0)
  135.   {
  136.     RotateAbout (v, player.up, player.view, theta*player.move_pitchleft);
  137.     Vset (player.up, v);
  138.     Normalize (player.up);
  139.     Crossp (player.right, player.up, player.view);
  140.     Normalize (player.right); 
  141.     player.still = 0;
  142.   }
  143.  
  144.   if (player.move_forward > 0.0)
  145.   {
  146.     if (player.flightmodel == FLIGHT_NEWTONIAN)
  147.     {
  148.       if (warpspeed) 
  149.       {
  150.         if (superwarp && !am_client && !am_server) 
  151.         Vmul (v, player.view, 100.0*player.move_forward*DELTAV*deltaT); 
  152.         else 
  153.         Vmul (v, player.view, deltaT * (player.move_forward*DELTAV + WARP_COEFF*Mag(player.vel))); 
  154.       }
  155.       else
  156.       Vmul (v, player.view, player.move_forward*DELTAV*deltaT);
  157.       Vadd (deltav, deltav, v);
  158.     }
  159.     else
  160.     {
  161.       if (player.throttle < MAX_THROTTLE)
  162.       {
  163.         if (warpspeed)
  164.         player.throttle += 10.0*player.move_forward*DELTAV*deltaT;
  165.         else
  166.         player.throttle += player.move_forward*DELTAV*deltaT;
  167.       }
  168.       else
  169.       {
  170.         if (warpspeed)
  171.         player.throttle += 10.0*100.0*player.move_forward*DELTAV*deltaT;
  172.         else
  173.         player.throttle += 100.0*player.move_forward*DELTAV*deltaT;
  174.       }
  175.       if (player.throttle > MAX_WARP_THROTTLE)
  176.       player.throttle = MAX_WARP_THROTTLE;
  177.     }
  178.     player.still = 0;
  179.   }
  180.  
  181.   if (player.move_backward > 0.0)
  182.   {
  183.     if (player.flightmodel == FLIGHT_NEWTONIAN)
  184.     {
  185.       if (warpspeed) 
  186.       {
  187.         if (superwarp && !am_client && !am_server)
  188.         Vmul (v, player.view, -100.0*player.move_backward*DELTAV*deltaT); 
  189.         else
  190.         Vmul (v, player.view, -deltaT * (player.move_backward*DELTAV + WARP_COEFF*Mag(player.vel))); 
  191.       }
  192.       else
  193.       Vmul (v, player.view, -player.move_backward*DELTAV*deltaT);
  194.       Vadd (deltav, deltav, v);
  195.     }
  196.     else
  197.     {
  198.       if (player.throttle < MAX_THROTTLE)
  199.       {
  200.         if (warpspeed)
  201.         player.throttle -= 10.0*player.move_backward*DELTAV*deltaT;
  202.         else
  203.         player.throttle -= player.move_backward*DELTAV*deltaT;
  204.       }
  205.       else
  206.       {
  207.         if (warpspeed)
  208.         player.throttle -= 100.0*10.0*player.move_backward*DELTAV*deltaT;
  209.         else
  210.         player.throttle -= 100.0*player.move_backward*DELTAV*deltaT;
  211.       }
  212.       if (player.throttle < 0.0) player.throttle = 0.0;
  213.     }
  214.     player.still = 0;
  215.   }
  216.  
  217.   /* Compute change to velocity */
  218.   if (player.flightmodel == FLIGHT_NEWTONIAN)
  219.   {
  220.     Vadd (player.vel, player.vel, deltav);
  221.   }
  222.   else
  223.   {
  224.     Vmul (player.vel, player.view, player.throttle);
  225.   }
  226.  
  227.   /* Compute gravity's contribution */
  228.   if (gravity && (player.flightmodel == FLIGHT_NEWTONIAN) )
  229.   {
  230.     Gravity (deltav, player.pos);
  231.     Vadd (player.vel, player.vel, deltav);
  232.   }
  233.  
  234.   /* Finaly, move player */
  235.   Vmul (v, player.vel, deltaT);
  236.   Vadd (player.pos, player.pos, v);
  237.  
  238.   /* See if player cratered on the planet */
  239.   if (vulnerable)
  240.   {
  241.     if (-1 != (p = InsidePlanet (player.pos)))
  242.     {
  243.       if (!am_client && !am_server) 
  244.       {
  245.         /* Make an explosion */
  246.         Vsub (v, player.pos, planet[p].pos);
  247.         Vmul (v, v, planet[p].radius*1.05);
  248.         Vadd (v, v, planet[p].pos);
  249.         Boom (v, 1.0);
  250.  
  251.         /* Send player back home */
  252.         InitPlayer();
  253.         gravity = 0;
  254.         ReadMission (mission.fn);
  255.  
  256.         /* Give the bad news */
  257.         sprintf (buf, "You hit %s and died!\\\\Restarting mission.",
  258.         planet[p].name);
  259.         Mprint (buf); 
  260.       }
  261.       else if (am_server) 
  262.       {
  263.         NetTargetCratered (client[server.client].target, p); 
  264.         NetPlayerDies(); 
  265.         
  266.         sprintf (buf, "You hit %s and died!", planet[p].name); 
  267.         Mprint (buf); 
  268.       }
  269.     }
  270.   }
  271.  
  272.   /* In network games, update position of target for the player */
  273.   if (am_client || am_server)
  274.   {
  275.     if (am_client) t = client[clientme.client].target;
  276.     if (am_server) t = client[server.client].target;
  277.  
  278.     Vset (target[t].pos, player.pos);
  279.     Vset (target[t].vel, player.vel);
  280.     Vset (target[t].up, player.up);
  281.     Vset (target[t].view, player.view);
  282.  
  283.     target[t].move_up = player.move_up;
  284.     target[t].move_down = player.move_down;
  285.     target[t].move_right = player.move_right;
  286.     target[t].move_left = player.move_left;
  287.     target[t].move_pitchright = player.move_pitchright;
  288.     target[t].move_pitchleft = player.move_pitchleft;
  289.   }
  290.   
  291.   /* If we've gone from still to not still, or other way around, 
  292.     send position report */ 
  293.   if (was_still != player.still) 
  294.   {
  295.     if (am_client) clientme.urgent = 1; 
  296.     QueuePositionReport(); 
  297.   }
  298. }
  299.  
  300. void UpdatePlayer()
  301. /*
  302.  *  Update all sorts of stuff for the player
  303.  */
  304. {
  305.   MovePlayer();
  306.  
  307.   /* Maintain shields */
  308.   player.shields += deltaT * SHIELD_REGEN;
  309.   if (player.shields > player.maxshields)
  310.   player.shields = player.maxshields;
  311.  
  312.   /* Weapon idle time */
  313.   player.msl_idle += deltaT; 
  314.   
  315.   /* Dead time */ 
  316.   if (state == STATE_DEAD1) 
  317.   {
  318.     player.dead_timer -= deltaT; 
  319.     if (player.dead_timer <= 0.0) 
  320.     {
  321.       state = STATE_DEAD2; 
  322.       player.dead_timer = 0.0; 
  323.     }
  324.   }
  325. }
  326.  
  327. void PlayerFires()
  328. /*
  329.  *  Player maybe fires a missile
  330.  */
  331. {
  332.   double v[3];
  333.  
  334.   paused = 0; 
  335.   
  336.   /* Not if dead */ 
  337.   if (state == STATE_DEAD1) return; 
  338.   
  339.   /* Fire button respawns us */ 
  340.   if (state == STATE_DEAD2) 
  341.   {
  342.     state = STATE_NORMAL; 
  343.     return; 
  344.   }
  345.  
  346.   /* Can't fire too rapidly */
  347.   if (player.msl_idle < weapon[player.weapon].idle)
  348.   {
  349.     return;
  350.   }
  351.   player.msl_idle = 0.0;
  352.  
  353.   /* Okay, fire the missile */
  354.   Vmul (v, player.up, -0.01);
  355.   Vadd (v, v, player.pos);
  356.   FireMissile (v, player.vel, player.view, 1, player.weapon, -1);
  357.  
  358.   /* Send network notification */
  359.   if (am_client)
  360.   {
  361.     SendASCIIPacket (clientme.socket, "FIRE %d", player.weapon);
  362.   }
  363.  
  364.   if (am_server)
  365.   {
  366.     NetClientFires (server.client, player.weapon);
  367.   }
  368. }
  369.  
  370. void DoName()
  371. /* 
  372.  *  Sparky has typed a new name 
  373.  */ 
  374. {
  375.   int i, len; 
  376.   
  377.   len = strlen (text.buf); 
  378.   
  379.   /* Remove spaces */ 
  380.   for (i=0; i<len; i++) 
  381.   {
  382.     if (text.buf[i] == ' ') text.buf[i] = '_'; 
  383.   }
  384.   strcpy (player.name, text.buf); 
  385. }
  386.  
  387. void ViewLock()
  388. /* 
  389.  *  Aim player toward locked object 
  390.  */ 
  391. {
  392.   double pos[3], v[3]; 
  393.   
  394.   v[0] = 1.0; v[1] = 0.0; v[2] = 0.0; 
  395.   
  396.   /* Not if we're not locked */ 
  397.   if (lock.target == (-1)) return; 
  398.   
  399.   /* Figure out what we're locked on */ 
  400.   if (lock.type == LOCK_ENEMY) 
  401.   {
  402.     Vset (pos, target[lock.target].pos); 
  403.   }
  404.   else if (lock.type == LOCK_FRIENDLY) 
  405.   {
  406.     Vset (pos, target[lock.target].pos); 
  407.   }
  408.   else if (lock.type == LOCK_PLANET) 
  409.   {
  410.     Vset (pos, planet[lock.target].pos); 
  411.   }
  412.   else 
  413.   {
  414.     /* Can't happen */ 
  415.     Log ("ViewLock: Invalid lock.type"); 
  416.     return; 
  417.   }
  418.   
  419.   /* Set view vector */ 
  420.   Vsub (player.view, pos, player.pos); 
  421.   Normalize (player.view); 
  422.   
  423.   /* Set up vector */ 
  424.   /* Perp (player.up, player.view); */ 
  425.   Crossp (player.up, player.view, v); 
  426.   Normalize (player.up); 
  427.   
  428.   /* Try to keep the up vector pointing up */ 
  429.   /* if (player.up[2] < player.pos[2]) Vmul (player.up, player.up, -1.0); */ 
  430.   
  431.   /* Set right-hand vector */ 
  432.   Crossp (player.right, player.up, player.view); 
  433. }
  434.